package com.quick.develop.flowable.service.task.impl;

import com.quick.develop.flowable.enums.BpmExecuteCmd;
import com.quick.develop.framework.utils.collection.CollectionUtils;
import com.quick.develop.framework.security.utils.SecurityUtils;
import com.quick.develop.flowable.framework.factory.FlowServiceFactory;
import com.quick.develop.flowable.utils.FlowableUtil;
import com.quick.develop.flowable.mapper.BpmCommentMapper;
import com.quick.develop.flowable.service.task.IBpmCommentService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.task.Comment;
import org.flowable.engine.task.Event;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author junyuan.liu
 * @description: TODO
 * @date 2022/7/1 14:27
 */
@Service
@Slf4j
public class BpmCommentServiceImpl extends FlowServiceFactory implements IBpmCommentService {
    @Resource
    BpmCommentMapper bpmCommentMapper;


    @Override
    public List<Comment> getTaskCommentByTaskId(String id) {
        return Optional.ofNullable(id)
                .map(p -> taskService.getTaskComments(p))
                .orElse(Collections.emptyList());
    }

    @Override
    public Map<String, List<Comment>> getTaskCommentsByTaskIds(Set<String> ids) {
        List<Comment> comments = bpmCommentMapper.selectCommentsByTaskId(ids);
        
        return CollectionUtils.convertMultiMap(comments, Comment::getTaskId);
    }

    @Override
    public List<Comment> getTaskCommentByProcessId(String processInstanceId) {
        return Optional.ofNullable(processInstanceId)
                .map(p -> taskService.getProcessInstanceComments(p))
                .orElse(Collections.emptyList());
    }

    @Override
    public List<Comment> getTaskCommentByProcessIds(Collection<String> processInstanceIds) {
        return Optional.ofNullable(processInstanceIds)
                .map(p -> bpmCommentMapper.selectCommentsByProcessInstanceIds(p))
                .orElse(Collections.emptyList());
    }

    @Override
    public List<Event> getTaskEvents(String taskId) {
        return Optional.ofNullable(taskId)
                .map(p -> taskService.getTaskEvents(p))
                .orElse(Collections.emptyList());
    }

    @Override
    public void addComment(String taskId, String processInstanceId, String message, BpmExecuteCmd cmd, String txt) {
        String userCode = SecurityUtils.getUserCode();
        String user = SecurityUtils.getUserCodeName();
        BpmExecuteCmd finalCmd = Objects.isNull(cmd) ? BpmExecuteCmd.DEFAULT :  cmd;
        StringBuilder comment = new StringBuilder();
        if (BpmExecuteCmd.DELEGATE == finalCmd || BpmExecuteCmd.ASSIGN == finalCmd ) {
            comment.append(finalCmd.msg).append("：").append(user)
                    .append(" → ").append(txt);
        }
        else if (BpmExecuteCmd.CLAIM == finalCmd ||BpmExecuteCmd.UN_CLAIM == finalCmd) {
            comment.append(user).append(finalCmd.getMsg());
        }
        else if (BpmExecuteCmd.WITHDRAW == finalCmd ) {
            comment.append("由").append(user).append(finalCmd.msg)
                    .append("到：").append(txt);
        }
        else if (BpmExecuteCmd.BACK == finalCmd) {
            comment.append("退回到：").append(txt);
        }
        else if (BpmExecuteCmd.STOP == finalCmd) {
            comment.append("流程由：").append(user).append("终止");
        }

        Optional.ofNullable(message)
                .ifPresent(c -> {
                    if (comment.length() == 0){
                        comment.append(c);
                    }else {
                        comment.append("；").append(c);
                    }
                });
        FlowableUtil.setAuthenticatedUserId(userCode);
        taskService.addComment(taskId, processInstanceId, finalCmd.getCmd(), comment.toString());
        FlowableUtil.clearAuthenticatedUserId();
    }
}
